﻿#include "OiPCH.hpp"
#include "OiTitleWidget.hpp"

namespace Oi
{
    namespace PLScannerCore
    {
        class TitleLabel : public QLabel
        {
        public:
            TitleLabel(QWidget *parent = Q_NULLPTR) : QLabel(parent)
            {
                _color = Qt::black;
                _shadow = QColor(50, 50, 50);
            }

            void setTextColor(QColor color)
            {
                _color = color;
            }

            void setShadowColor(QColor color)
            {
                _shadow = color;
            }

        protected:
            void paintEvent(QPaintEvent * event)
            {
                QPainter painter(this);

                qreal ww = this->width();
                qreal wh = this->height();

                auto pen = painter.pen();

                auto fontbg = this->font();
                fontbg.setPixelSize(fontbg.pixelSize());
                fontbg.setBold(true);

                QFontMetricsF fontMetricsbg(fontbg);

                qreal bgw = fontMetricsbg.width(this->text());

                qreal bgh = fontMetricsbg.height();

                qreal bgl = ( ww - bgw ) / 2.0;
                qreal bgt = ( wh - bgh ) / 2.0;

                auto fontT = this->font();
                fontT.setPixelSize(fontT.pixelSize() - 1);

                QFontMetricsF fontMetricsT(fontT);

                qreal tw = fontMetricsT.width(this->text());

                qreal th = fontMetricsT.height();

                qreal tl = ( ww - tw ) / 2.0;
                qreal tt = ( wh - th ) / 2.0;

                painter.save();

                painter.setPen(QPen(_color, pen.width()));
                painter.setFont(fontT);
                painter.drawStaticText(tl, tt, QStaticText(this->text()));

                painter.restore();

            }

        private:
            QColor _color;
            QColor _shadow;
        };

        class TitleWidgetImpl : public Impl<TitleWidget>
        {
        public:
            void init();

        public:
            QImage _bg;
            QColor _bgColor;
        };

        void TitleWidgetImpl::init()
        {
            OI_Q(TitleWidget);
            q->setMouseTracking(true);
            q->setFixedHeight(80);
            q->setCursor(Qt::ArrowCursor);

            _bgColor = PLScannerStyle::TitleBackgroundColor();

            _bg = QImage(":/resources/images/bg.png");
        }

        TitleWidget::TitleWidget(QWidget * parent) : QWidget(parent)
        {
            OI_I(TitleWidget)->init();
        }

        TitleWidget::~TitleWidget()
        {
            OI_E(TitleWidget);
        }

        void TitleWidget::paintEvent(QPaintEvent *event)
        {
            OI_F(TitleWidget);

            QPainter p(this);

            p.fillRect(rect(), d->_bgColor);
        }

        class TitleButtonImpl : public Impl<TitleButton>
        {
        public:
            void init(QBoxLayout::Direction dir);
        public:
            QAction* _action;
            bool _isChecked;
            bool _isTouched;
            QLabel* _icon;
            TitleLabel* _text;
            int _markOrientation;
            int _markWidth;
            QColor _bgColor;
        };

        void TitleButtonImpl::init(QBoxLayout::Direction dir)
        {
            OI_Q(TitleButton);

            QBoxLayout* layout = new QBoxLayout(dir, q);
            layout->setContentsMargins(0, 0, 0, 0);
            layout->setSpacing(0);

            _icon = new QLabel(q);
            _text = new TitleLabel(q);

            layout->addWidget(_icon);
            layout->addWidget(_text);

            q->setMouseTracking(true);
            q->setObjectName("TitleButton");
            _text->setObjectName("Text");
            _icon->setContentsMargins(5, 5, 5, 5);
            _icon->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            _text->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            _text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
            _action = new QAction(q);
            _action->setCheckable(true);
            _icon->hide();

            _markOrientation = 0;
            _markWidth = 5;

            q->setChecked(false);
            q->setTouched(false);

            q->connect(q, SIGNAL(triggered()), _action, SLOT(trigger()));
            q->connect(_action, SIGNAL(toggled(bool)), q, SLOT(setChecked(bool)));
        }

        TitleButton::TitleButton(QBoxLayout::Direction dir, QWidget* parent) : QWidget(parent)
        {
            OI_I(TitleButton)->init(dir);
        }

        TitleButton::~TitleButton()
        {
            OI_E(TitleButton);
        }

        QAction* TitleButton::action()
        {
            return OI_IMPL()->_action;
        }

        void TitleButton::setAction(QAction* action, const QString icon)
        {
            OI_F(TitleButton);
            setIcon(icon);
            setText(action->text());
            d->_action = action;

            connect(this, SIGNAL(triggered()), d->_action, SLOT(trigger()));
            connect(d->_action, SIGNAL(toggled(bool)), this, SLOT(setChecked(bool)));
        }

        void TitleButton::setIcon(const QString path)
        {
            QPixmap pixmap = QPixmap(path);
            OI_IMPL()->_icon->setPixmap(pixmap);
            OI_IMPL()->_icon->show();
        }

        void TitleButton::setText(const QString text)
        {
            QFont font = OI_IMPL()->_text->font();
            font.setPixelSize(16);
            OI_IMPL()->_text->setFont(font);
            OI_IMPL()->_text->setText(text);
        }

        void TitleButton::setMarkWidth(int markWidth)
        {
            OI_IMPL()->_markWidth = markWidth;
        }

        void TitleButton::setMarkOrientation(int orientation)
        {
            OI_IMPL()->_markOrientation = orientation;
        }

        void TitleButton::setBackgroundColor(const QColor bgColor)
        {
            OI_IMPL()->_bgColor = bgColor;
        }

        bool TitleButton::isChecked()
        {
            return OI_IMPL()->_isChecked;
        }

        void TitleButton::setChecked(bool isChecked)
        {
            OI_F(TitleButton);
            d->_isChecked = isChecked;
            if(d->_isChecked)
            {
                d->_text->setTextColor(Qt::black);
            }
            else
            {
                d->_text->setTextColor(PLScannerStyle::TitleForegroundColor());
            }
            update();
        }

        void TitleButton::setTouched(bool isTouched)
        {
            OI_F(TitleButton);
            d->_isTouched = isTouched;

            if(d->_isChecked)
            {
                return;
            }
            if(d->_isTouched)
            {
                d->_text->setTextColor(Qt::black);
            }
            else
            {
                d->_text->setTextColor(PLScannerStyle::TitleForegroundColor());
            }
            update();
        }

        void TitleButton::enterEvent(QEvent *event)
        {
            setTouched(true);
        }

        void TitleButton::leaveEvent(QEvent *event)
        {
            setTouched(false);
        }

        void TitleButton::mousePressEvent(QMouseEvent *event)
        {
            if(event->button() & Qt::LeftButton)
            {
                setChecked(true);
                emit triggered();
            }
        }

        void TitleButton::mouseReleaseEvent(QMouseEvent *event)
        {
            OI_F(TitleButton);

            if(event->button() & Qt::LeftButton)
            {
                if (!d->_action->isCheckable())
                {
                    setChecked(false);
                }
            }
        }

        void TitleButton::paintEvent(QPaintEvent *event)
        {
            OI_F(TitleButton);

            QPainter p(this);
            p.setPen(Qt::NoPen);

            QRect backgroundRect = rect();
            backgroundRect.adjust(0, 0, 0, 0);

            QPainterPath backgroundPath;
            backgroundPath.addRect(backgroundRect);

            if(d->_markOrientation == 1)
            {
                QPolygonF marks;
                QPoint tc(backgroundRect.center().x(), backgroundRect.top());
                QPointF p1(tc.x() - d->_markWidth, tc.y() - 1);
                QPointF p2(tc.x() + d->_markWidth, tc.y() - 1);
                QPointF p3(tc.x(), tc.y() + d->_markWidth - 1);
                marks << p1 << p2 << p3 << p1;
                backgroundPath.addPolygon(marks);
            }
            if(d->_markOrientation == 2)
            {
                QPolygonF marks;
                QPoint tc(backgroundRect.right(), backgroundRect.center().y());
                QPointF p1(tc.x() + 1, tc.y() - d->_markWidth);
                QPointF p2(tc.x() + 1, tc.y() + d->_markWidth);
                QPointF p3(tc.x() - d->_markWidth + 1, tc.y());
                marks << p1 << p2 << p3 << p1;
                backgroundPath.addPolygon(marks);
            }
            if(d->_markOrientation == 3)
            {
                QPolygonF marks;
                QPoint tc(backgroundRect.center().x(), backgroundRect.bottom());
                QPointF p1(tc.x() - d->_markWidth, tc.y() + 1);
                QPointF p2(tc.x() + d->_markWidth, tc.y() + 1);
                QPointF p3(tc.x(), tc.y() - d->_markWidth + 1);
                marks << p1 << p2 << p3 << p1;
                backgroundPath.addPolygon(marks);
            }
            if(d->_markOrientation == 4)
            {
                QPolygonF marks;
                QPoint tc(backgroundRect.left(), backgroundRect.center().y());
                QPointF p1(tc.x() - 1, tc.y() - d->_markWidth);
                QPointF p2(tc.x() - 1, tc.y() - d->_markWidth);
                QPointF p3(tc.x() + d->_markWidth - 1, tc.y());
                marks << p1 << p2 << p3 << p1;
                backgroundPath.addPolygon(marks);
            }

            if(d->_bgColor.isValid())
            {
                p.setBrush(d->_bgColor);
                if(d->_isChecked)
                {
                    p.drawPath(backgroundPath);
                }
                else
                {
                    p.drawRect(backgroundRect);
                }
            }

            if(d->_isTouched && !d->_isChecked)
            {
                p.setBrush(QColor(255, 217, 208, 150));
                p.drawRect(backgroundRect);
            }
            else if(d->_isChecked)
            {
                p.setBrush(QColor(180, 180, 180, 200));

                if(d->_isChecked)
                {
                    p.drawPath(backgroundPath);
                }
                else
                {
                    p.drawRect(backgroundRect);
                }
            }
            else
            {
                p.setBrush(QColor(0, 0, 0, 0));
                p.drawRect(backgroundRect);
            }
        }

    }
}
